/*
"JSFXGEN" - UIScrollBar.as
Modular Integrated Development Environment for JesuSonic
Project page: http://jsfxgen.googlecode.com

Copyright 2009 Lubomir I. Ivanov

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package neolit123.ui
{
  import flash.display.Sprite;
  import flash.display.Stage;
  import flash.display.MovieClip;
  import flash.events.Event;
  import flash.events.MouseEvent;
  import flash.geom.Rectangle;
  // =========================================================
  public class UIScrollScriptAreaV extends Sprite
  {
    // =========================================================
    private var scroll_sp:Sprite;
    private var drag_mc:MovieClip;
    private var drag_sp:Sprite;
    private var drag:Box;
    private var smb:Box;
    private var track:Box;
    private var dmask:Box;    
    private var stgt:Object;
    private var rect:Rectangle;
    private var range:Number;
    private var oldth:Number;
    private var oldh:Number;
    private var oldvs:Number;
    private var smbmet:Number;
    /*
    =========================================================
    parameters are:
    object, width, height, colordrag0, colordrag1, colortrack0, colortrack1
    */
    public function UIScrollScriptAreaV(...p:Array):void
    {
      // @ cacheAsBitmap = true;
      //cacheAsBitmap = true;
      // @ get properties
      if (p[0] == null || p[0] == undefined) p[0] = stgt;
      if (p[1] == null || p[1] == undefined) p[1] = 15;
      if (p[2] == null || p[2] == undefined) p[2] = 100;
      if (p[3] == null || p[3] == undefined) p[3] = 0x0072ba;
      if (p[4] == null || p[4] == undefined) p[4] = 0x000000;
      if (p[5] == null || p[5] == undefined) p[5] = 0xeeeeee;
      if (p[6] == null || p[6] == undefined) p[6] = 0x000000;
      // @ create objects
      drag = new Box(p[1],20,p[3],p[4],false);
      track = new Box(p[1],p[2],p[5],p[6],false);
      dmask = new Box(p[1],p[2],0x00ff00,0x00ff00,false);
      smbmet = p[1]*0.5;
      smb = new Box(smbmet,smbmet,p[5],p[6],false);
      scroll_sp = new Sprite();
      drag_sp = new Sprite();
      drag_mc = new MovieClip();
      // @ assign target to private variable 
      stgt = p[0];
      // @ add objects
      addChild(scroll_sp);
      scroll_sp.addChild(track);
      scroll_sp.addChild(dmask);
      scroll_sp.addChild(drag_mc);
      drag_mc.addChild(drag_sp);
      drag_sp.addChild(drag);
      drag_sp.addChild(smb);
      drag_mc.mask = dmask;
      smb.x = (((p[1]-smbmet)*0.5)>>0) + 1;
      // @ set drag
      drag_sp.buttonMode = true;
      drag_sp.mouseChildren = false;
      drag_sp.addEventListener(MouseEvent.MOUSE_DOWN, startdrag);
      drag_sp.addEventListener(MouseEvent.MOUSE_OVER, rollover);
      drag_sp.addEventListener(MouseEvent.MOUSE_OUT, rollout);  
      // @ set track
      track.buttonMode = true;
      track.mouseChildren = false;
      track.addEventListener(MouseEvent.MOUSE_DOWN, clicktrack);
      // @ update scroller on text change
      stgt.addEventListener(Event.SCROLL, updatescroller);
      stgt.addEventListener(Event.CHANGE, updatescroller);
      // @ first update
      updatescroller(null);
      update();
    }
    // =========================================================
    // [ set drag dimentions
    // =========================================================
    private function setrect():void
    {
      range = track.height - drag_mc.height;
      rect = new Rectangle(0, 0, 0, range);
      updatescrollerposition(null);
    }
    // =========================================================
    // [ drag scroller
    // =========================================================
    private function startdrag(e:MouseEvent):void
    {
      drag.alpha = 0.8;
      drag_sp.removeEventListener(MouseEvent.MOUSE_OUT, rollout);
      drag_mc.stage.addEventListener(MouseEvent.MOUSE_UP, stopdrag);
      drag_mc.stage.addEventListener(Event.ENTER_FRAME, dragf);
      drag_mc.startDrag(false, rect);
      stgt.removeEventListener(Event.SCROLL, updatescroller);
    }
    // =========================================================
    // [ stop drag
    // =========================================================
    private function stopdrag(e:MouseEvent):void
    {
      drag.alpha = 1;
      drag_sp.addEventListener(MouseEvent.MOUSE_OUT, rollout);
      drag_mc.stage.removeEventListener(MouseEvent.MOUSE_UP, stopdrag);
      drag_mc.stage.removeEventListener(Event.ENTER_FRAME, dragf);
      drag_mc.stopDrag();
      stgt.addEventListener(Event.SCROLL, updatescroller);
    }
    // =========================================================
    // [ click on scroller track
    // =========================================================
    private function clicktrack(e:MouseEvent):void
    {
      drag_mc.y = e.localY*track.scaleY - drag_mc.height*0.5;
      startdrag(null);
    }
    // =========================================================
    // [ call scroll from drag
    // =========================================================
    private function dragf(e:Event):void
    {
      callscroll(drag_mc.y/range);
    }
    // =========================================================
    // [ call scroll
    // =========================================================
    private function callscroll(n:Number):void
    {
      stgt.scrollY = (stgt.maxscroll+1)*n;
    }
    // =========================================================
    // [ update scroll position
    // =========================================================
    private function updatescrollerposition(e:Event):void
    {
      drag_mc.y = ((stgt.scrollY-1)/(stgt.maxscroll-1))*range;
    }
    // =========================================================
    // [ update scroller from text height
    // =========================================================
    private function updatescroller(e:Event=null):void
    {
      var newth:Number = stgt.textHeight;
      var stgth:Number = stgt.height;
      var vs:Number = stgt.scrollY;
      // @ update metrics on (text)height change
      if (oldth != newth || oldh != stgth || oldvs != vs)
      {
        var esth:Number = stgth*stgth/newth;
        drag.alpha = 1;
        drag_sp.mouseEnabled = true;
        if (esth>stgth)
        {
        esth = stgth; drag.alpha = 0.3; drag_sp.mouseEnabled = false;
        } else if (esth < smbmet+5) esth = smbmet+5;
        drag.height = esth;
        smb.y = (esth - smbmet)*0.5;
        oldth = newth;
        oldh = stgth;
        oldvs = vs;
        setrect();
      }
    }
    // =========================================================
    // [ update (public)
    // =========================================================
    public function update():void
    {
      scroll_sp.x = stgt.x+stgt.width;
      scroll_sp.y = stgt.y;
      dmask.height = stgt.height+1;
      track.height = stgt.height;
      updatescroller(null);      
    }
    // =========================================================
    // [ rollover / rollout
    // =========================================================
    private function rollover(e:MouseEvent=null):void
    {
      drag.alpha = 0.8;
    }
    private function rollout(e:MouseEvent=null):void
    {
      drag.alpha = 1;
    }
  }
}